from pprint import pprint

from rest_framework import serializers

from jqdelivery.models import UserExpressInfo, UserDeliveryOrder, UserDeliveryOrderGoods
from jqgame.basegame import GameType


class UserExpressInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserExpressInfo
        fields = [
            "uuid",
            "express_name",
            "express_phone",
            "express_area",
            "express_address",
        ]


class UpdateUserExpressInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserExpressInfo
        fields = [
            "uuid",
            "express_name",
            "express_phone",
            "express_area",
            "express_address",
        ]


class CreateUserExpressInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserExpressInfo
        fields = [
            "express_name",
            "express_phone",
            "express_area",
            "express_address",
        ]


_game_type_name = {
    GameType.wuxianshang: "无限赏",
    GameType.wuxianshang_boss: "无限赏-boss赏",
    GameType.quanjushang: "全局赏",
    GameType.yifanshang: "一番赏",
}


def get_game_name(game_type):
    """
    获取游戏类型的中文名称
    Args:
        game_type: 游戏类型

    Returns: 中文名称

    """
    return _game_type_name[game_type]


class UserDeliveryOrderGoodsSerializer(serializers.Serializer):
    uuid = serializers.UUIDField(read_only=True)
    package_uuid = serializers.UUIDField(read_only=True)
    game_type = serializers.StringRelatedField(read_only=True)
    game_type_name = serializers.SerializerMethodField()
    good_uuid = serializers.UUIDField(read_only=True)
    good_name = serializers.StringRelatedField(read_only=True)
    good_display_url = serializers.StringRelatedField(read_only=True)
    good_price = serializers.IntegerField(read_only=True)
    good_recovery_price = serializers.IntegerField(read_only=True)
    good_level_title = serializers.StringRelatedField(read_only=True)
    count = serializers.SerializerMethodField(read_only=True)
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_game_type_name(self, obj):
        game_type = obj.get("game_type")
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))

    def get_count(self, obj):
        return 1


class UserDeliveryOrderGoodsV2Serializer(serializers.Serializer):
    uuid = serializers.UUIDField(read_only=True)
    package_uuid = serializers.UUIDField(read_only=True)
    game_type = serializers.StringRelatedField(read_only=True)
    game_type_name = serializers.SerializerMethodField()
    good_uuid = serializers.UUIDField(read_only=True)
    good_name = serializers.StringRelatedField(read_only=True)
    good_display_url = serializers.StringRelatedField(read_only=True)
    good_price = serializers.IntegerField(read_only=True)
    good_recovery_price = serializers.IntegerField(read_only=True)
    good_level_title = serializers.StringRelatedField(read_only=True)
    sum_price = serializers.IntegerField(read_only=True)
    sum_recovery_price = serializers.IntegerField(read_only=True)
    sum_count = serializers.IntegerField(read_only=True)
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_game_type_name(self, obj):
        game_type = obj.get("game_type")
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))


class UserDeliveryOrderListSerializer(serializers.ModelSerializer):
    goods = serializers.SerializerMethodField(read_only=False)
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_goods(self, obj):
        _query_set = UserDeliveryOrderGoods.objects.filter(deleted=False).filter(
            delivery_order_uuid=obj.uuid
        )
        _query_set = _query_set.extra(
            select={
                "package_uuid": "UserPackageGoods.uuid",
                "good_uuid": "JuqiGood.uuid",
                "good_name": "JuqiGood.name",
                "good_display_url": "JuqiGood.display_url",
                "good_price": "JuqiGood.price",
                "good_recovery_price": "JuqiGood.recovery_price",
                "user_uuid": "UserPackageGoods.user_uuid",
                "game_type": "UserPackageGoods.game_type",
                "good_level_title": "UserPackageGoods.good_level_title",
            },
            tables=["UserPackageGoods", "JuqiGood"],
            where=[
                "UserDeliveryOrderGoods.user_package_uuid=UserPackageGoods.uuid",
                "UserDeliveryOrderGoods.good_uuid=JuqiGood.uuid",
                "JuqiGood.deleted=false",
                "UserDeliveryOrderGoods.deleted=false",
            ],
        ).values(
            "uuid",
            "user_uuid",
            "good_uuid",
            "good_name",
            "good_display_url",
            "game_type",
            "good_price",
            "good_recovery_price",
            "good_level_title",
            "createdAt",
        )

        _query_set = _query_set.order_by("-good_recovery_price")
        _good_all = _query_set[:5]
        _good_list = []
        for _good in _good_all:
            _good_list.append(UserDeliveryOrderGoodsSerializer(_good).data)
        return _good_list

    class Meta:
        model = UserDeliveryOrder
        fields = "__all__"


class UserDeliveryOrderDetailedSerializer(serializers.ModelSerializer):
    goods = serializers.SerializerMethodField(read_only=False)
    express = serializers.SerializerMethodField(read_only=False)

    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_goods(self, obj):
        _query_set = UserDeliveryOrderGoods.objects.filter(deleted=False).filter(
            delivery_order_uuid=obj.uuid
        )
        _query_set = _query_set.extra(
            select={
                "package_uuid": "UserPackageGoods.uuid",
                "good_uuid": "JuqiGood.uuid",
                "good_name": "JuqiGood.name",
                "good_display_url": "JuqiGood.display_url",
                "good_price": "JuqiGood.price",
                "good_recovery_price": "JuqiGood.recovery_price",
                "user_uuid": "UserPackageGoods.user_uuid",
                "game_type": "UserPackageGoods.game_type",
                "good_level_title": "UserPackageGoods.good_level_title",
            },
            tables=["UserPackageGoods", "JuqiGood"],
            where=[
                "UserDeliveryOrderGoods.user_package_uuid=UserPackageGoods.uuid",
                "UserDeliveryOrderGoods.good_uuid=JuqiGood.uuid",
                "JuqiGood.deleted=false",
                "UserDeliveryOrderGoods.deleted=false",
            ],
        ).values(
            "uuid",
            "user_uuid",
            "good_uuid",
            "good_name",
            "good_display_url",
            "game_type",
            "good_price",
            "good_recovery_price",
            "good_level_title",
            "createdAt",
        )

        _good_all = _query_set.order_by("-good_recovery_price")
        _good_list = []

        goods_dict = dict()
        for _goods in _good_all:
            _get_goods = goods_dict.get(_goods["good_uuid"])
            if _get_goods is None:
                goods_dict[_goods["good_uuid"]] = {
                    "good_name": _goods["good_name"],
                    "good_display_url": _goods["good_display_url"],
                    "good_price": _goods["good_price"],
                    "good_recovery_price": _goods["good_recovery_price"],
                    "game_type": _goods["game_type"],
                    "createdAt": _goods["createdAt"],
                    "good_level_title": _goods["good_level_title"],
                    "good_uuid": _goods["good_uuid"],
                    "sum_price": 0,
                    "sum_recovery_price": 0,
                    "sum_count": 0,
                }
            _refined_goods_cru = goods_dict[_goods["good_uuid"]]
            _refined_goods_cru["sum_price"] += _goods["good_price"]
            _refined_goods_cru["sum_recovery_price"] += _goods["good_recovery_price"]
            _refined_goods_cru["sum_count"] += 1
        good_list = list(goods_dict.values())
        for _good in good_list:
            _good_list.append(UserDeliveryOrderGoodsV2Serializer(_good).data)
        return _good_list

    def get_express(self, obj):
        user_uuid = obj.user_uuid
        user_express_info_uuid = obj.user_express_info_uuid

        if user_uuid is None:
            return None
        if user_express_info_uuid is None:
            return None

        user_express_info = (
            UserExpressInfo.objects.filter(user_uuid=user_uuid)
            .filter(uuid=user_express_info_uuid)
            .first()
        )
        return UserExpressInfoSerializer(user_express_info).data

    class Meta:
        model = UserDeliveryOrder
        fields = "__all__"
